package behavior.Observer;

/**
 * Created by LYJ on 2016/10/21.
 * 详细链接：Observer（观察者）http://blog.csdn.net/u013256816/article/details/51245002
 */
public class MainTest {
    public static void main(String... args) {
        //推模型 主题对象向观察者推送主题的详细信息，不管观察者是否需要，推送的信息通常是主题对象的全部或部分数据。
        ConcreteSubject subject=new ConcreteSubject();
        Observer observer=new ConcreteObserver();
        subject.attach(observer);
        subject.setSubjectState("新状态");
        System.out.println("-----------");
        /**
         * 拉模型：主题对象在通知观察者的时候，只传递少量信息。如果观察者需要更具体的信息，由观察者主动到主题对象中获取，
         * 相当于是观察者从主题对象中拉数据。一般这种模型的实现中，会把主题对象自身通过update()
         * 方法传递给观察者，这样在观察者需要获取数据的时候，就可以通过这个引用来获取了
         */
        ConcreteSubject2 subject2 = new ConcreteSubject2();
        Observer2 observer2 = new ConcreteObserver2();
        subject2.attach(observer2);
        subject2.setState("new State");
    }
}
/**
 * 两种模式比较：
 推模型假定主题对象知道观察者需要的数据；而拉模型是主题对象不知道观察者具体需要什么数据，
 没有办法的情况下，干脆把自身传递给观察者，让观察者自己取按需要取值。
 推模型可能会使得观察者对象难以复用，因为观察者的update()方法是按需要定义的参数，
 可能无法兼顾没有考虑到的使用情况。这就意味着出现新情况的时候，就可能提供新的update()方法，
 或者是干脆重新实现观察者；而拉模型就不会造成这样的情况，因为拉模型下，update()方法的参数是主题对象本身，
 这基本上是主题对象能传递的最大数据集合了，基本上可以适应各种情况的需要。
 优缺点
 优点：
 1. Subject和Observer之间是松耦合的，分别可以各自独立改变。
 2. Subject在发送广播通知的时候，无需指定具体的Observer,Observer可以自己决定是否要订阅Subject的通知。
 缺点：
 1. 松耦合导致代码关系不明显，有时可能难以理解
 2. 如果一个Subject被大量Observer订阅的话，在广播通知的时候可能会有效率问题。
 适用场景
 1. 对一个对象状态的更新，需要其他对象同步更新，而且其他对象的数量动态改变。
 2. 对象仅需要将自己的更新通知给其他对象而不需要知道其他对象的细节。
 JDK中的观察者模式：
 Java.util.EventListener
 javax.servlet.http.HttpSessionBindingListener
 javax.servlet.http.HttpSessionAttributeListener
 javax.faces.event.PhaseListener
 */
